package com.information.manage.basic.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.information.manage.basic.model.entity.DictionaryInfoDO;
import com.information.manage.basic.model.query.AddDictionaryInfoQuery;
import com.information.manage.basic.model.query.UpdateDictionaryInfoQuery;
import com.information.manage.basic.model.vo.DictionaryInfoListVO;
import com.information.manage.basic.common.result.Result;
import com.information.manage.basic.mapper.DictionaryInfoMapper;
import com.information.manage.basic.service.DictionaryInfoService;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Arrays;
import java.util.List;

@Service
public class DictionaryInfoServiceImpl extends ServiceImpl<DictionaryInfoMapper, DictionaryInfoDO> implements DictionaryInfoService {

    @Resource
    private DictionaryInfoMapper dictionaryInfoMapper;

    @Override
    public Result<Integer> addDictionaryInfo(AddDictionaryInfoQuery addDictionaryInfoQuery) {
        Integer count = dictionaryInfoMapper.selectCount(new LambdaQueryWrapper<DictionaryInfoDO>()
                .eq(DictionaryInfoDO::getDictionaryCategoryId, addDictionaryInfoQuery.getCategoryId())
                .eq(DictionaryInfoDO::getName, addDictionaryInfoQuery.getName()));
        // 当前字典项已经存在
        if (count != 0) return Result.fail("当前字典类别下已存在该字典项, 添加失败");
        DictionaryInfoDO dictionaryInfoDO = new DictionaryInfoDO();
        dictionaryInfoDO.setDictionaryCategoryId(addDictionaryInfoQuery.getCategoryId());
        dictionaryInfoDO.setName(addDictionaryInfoQuery.getName());
        dictionaryInfoDO.setRemark(addDictionaryInfoQuery.getRemark());
        //获取当前字典类别下的字典排序的最后一层
        Integer maxLevel = (Integer) dictionaryInfoMapper.selectObjs(new LambdaQueryWrapper<DictionaryInfoDO>()
                .select(DictionaryInfoDO::getSequence).eq(DictionaryInfoDO::getDictionaryCategoryId, addDictionaryInfoQuery.getCategoryId())
                .orderByDesc(DictionaryInfoDO::getSequence)).stream().findFirst().orElse(null);
        if (maxLevel != null) dictionaryInfoDO.setSequence(++maxLevel);  // 已存在设置层级为+1
        else dictionaryInfoDO.setSequence(1); //不存在设置层级为1
        dictionaryInfoMapper.insert(dictionaryInfoDO);
        return Result.ok(dictionaryInfoDO.getId());
    }

    @Override
    public Result<Boolean> updateDictionaryInfo(UpdateDictionaryInfoQuery updateDictionaryInfoQuery) {
        DictionaryInfoDO dictionaryInfoDO = dictionaryInfoMapper.selectOne(new LambdaQueryWrapper<DictionaryInfoDO>()
                .eq(DictionaryInfoDO::getId, updateDictionaryInfoQuery.getId()));
        if (!dictionaryInfoDO.getDictionaryCategoryId().equals(updateDictionaryInfoQuery.getCategoryId())) return Result.fail("不能更改字典类别");
        if (updateDictionaryInfoQuery.getName() != null && !"".equals(updateDictionaryInfoQuery.getName().trim())){
            if (dictionaryInfoMapper.selectCount(new LambdaQueryWrapper<DictionaryInfoDO>()
                    .eq(DictionaryInfoDO::getName, updateDictionaryInfoQuery.getName())
                    .ne(DictionaryInfoDO::getId, updateDictionaryInfoQuery.getId())) > 0){  //判断该字典名称已经存在（排除自身）
                return Result.fail("当前字典类别下已存在该字典项, 修改失败");
            }
            dictionaryInfoDO.setName(updateDictionaryInfoQuery.getName());
        }
        if (updateDictionaryInfoQuery.getRemark() != null && !"".equals(updateDictionaryInfoQuery.getRemark().trim())) dictionaryInfoDO.setRemark(updateDictionaryInfoQuery.getRemark());
        dictionaryInfoMapper.updateById(dictionaryInfoDO);
        return Result.ok(true);
    }

    @Override
    public Boolean moveDictionaryInfo(Integer id, Boolean up) {
        //获取当前层级的数据
        DictionaryInfoDO curData = dictionaryInfoMapper.selectOne(new LambdaQueryWrapper<DictionaryInfoDO>().eq(DictionaryInfoDO::getId, id));
        int order;
        if (up){ //上移
            //获取上一层级
            order = curData.getSequence()-1;
        }else { //下移
            //获取下一层级
            order = curData.getSequence()+1;
        }
        DictionaryInfoDO upOrDownData = dictionaryInfoMapper.selectOne(new LambdaQueryWrapper<DictionaryInfoDO>()
        .eq(DictionaryInfoDO::getDictionaryCategoryId, curData.getDictionaryCategoryId())
        .eq(DictionaryInfoDO::getSequence, order));
        //上移时不存在上一层级 下移时不存在下一层级  不能移动
        if (upOrDownData == null || upOrDownData.getSequence() == null) return false;
        //调换排序数据 order 更新
        //tmp 临时存储
        int tmp;
        tmp = curData.getSequence();
        curData.setSequence(upOrDownData.getSequence());
        upOrDownData.setSequence(tmp);
        //更新
        this.updateBatchById(Arrays.asList(curData, upOrDownData));
        return true;
    }

    @Override
    public Result<Boolean> deleteDictionaryInfo(List<Integer> ids) {
        for (Integer id : ids) {
            // 获取当前id对应的菜单项数据
            DictionaryInfoDO dictionaryInfoDO = dictionaryInfoMapper.selectOne(new LambdaQueryWrapper<DictionaryInfoDO>().eq(DictionaryInfoDO::getId, id));
            //将该用户该菜单id对应的相同父id下的层数在该id后的菜单数据上移
            //获取层级大于当前id对应的层级数据
            List<DictionaryInfoDO> list = dictionaryInfoMapper.selectList(new LambdaQueryWrapper<DictionaryInfoDO>()
                    .eq(DictionaryInfoDO::getDictionaryCategoryId, dictionaryInfoDO.getDictionaryCategoryId())
                    .gt(DictionaryInfoDO::getSequence, dictionaryInfoDO.getSequence()));
            for (DictionaryInfoDO data : list) {  //设置后面的所有层级+1
                dictionaryInfoMapper.update(null, new LambdaUpdateWrapper<DictionaryInfoDO>()
                        .eq(DictionaryInfoDO::getId, data.getId())
                        .set(DictionaryInfoDO::getSequence, data.getSequence() - 1));
            }
        }
        // 删除当前id的数据
        dictionaryInfoMapper.deleteBatchIds(ids);
        return Result.ok(true);
    }

    @Override
    public List<DictionaryInfoListVO> queryListByCategoryId(Integer categoryId) {
        List<DictionaryInfoListVO> dictionaryInfoListVOS = dictionaryInfoMapper.queryListByCategoryId(categoryId);
        return dictionaryInfoListVOS;
    }
}
